/*
 * DatagramBuilder Library: serialize/deserialize data to/from datagram
 * Copyright (C) 2008 Rakov Ilya <RakovIlya@gmail.com>
 *
 * This library can be distributed under the terms of the GNU LGPLv2.
 * See the file COPYING.LIB.
 */


#ifndef DATAGRAM_MARK_H_
#define DATAGRAM_MARK_H_


/**
 * @file Mark.h
 *
 * @brief Mark header file
 *
 * @date Dec 15, 2008
 * @author Rakov Ilya
 */


#include "Builder.h"
#include "Parser.h"
#include "SerializeImpl.h"


/**
 * @brief This template class provides an ability to mark position at the container
 * to Get/Set value at that position later.
 */
template <
           class T /**< Data type of the marked position */
         >
class Mark
{

  BOOST_STATIC_ASSERT( boost::is_fundamental<T>::value );


public:

  /**
   * @brief ctor
   */
  Mark();


  /**
   * @brief ctor
   *
   * @param value Initial value of the mark.
   */
  Mark( const T &value );


  /**
   * @brief Sets value.
   *
   * Method sets data to the container if mark is binded
   */
  inline void Set( const T &value );


  /**
   * @brief Get value.
   *
   * Method gets data from the container if mark is binded
   */
  inline const T& Get() const;


  /**
   * @brief Binds mark with builder
   */
  inline void Bind( const Builder &builder ) const;


  /**
   * @brief Binds mark with parser
   */
  inline void Bind( const Parser &parser ) const;


  /**
   * @brief Flag whether the mark is already binded
   */
  inline bool IsBinded() const;


  /**
   * @brief Compares marks
   */
  inline bool operator ==( const Mark &other ) const;


  /**
   * @brief Compares marks
   */
  inline bool operator !=( const Mark &other ) const;


private:  // implementation

  inline void Bind( const Container &container, size_t offset ) const;


private:  // implementation

  mutable Container container_;
  mutable size_t    offset_;

  mutable T value_;

};


/**
 * @brief Helper function for creation instances of the Mark.
 */
template< class T >
inline Mark< T > mark( const T &value );


/** @relates Mark
 *
 * @brief Provides an ability to output the Mark's state into an output streams.
 *
 * @param out Output stream
 * @param obj Mark
 */
template< class CharType, class CharTrait, class T >
inline std::basic_ostream< CharType, CharTrait >&
operator <<( std::basic_ostream<CharType, CharTrait> &out, const Mark<T> &obj );


#include "impl/MarkImpl.h"

#endif /* DATAGRAM_MARK_H_ */
